package vista.objetos;

import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.util.Observable;

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.awt.GLJPanel;
import javax.swing.JFrame;
import javax.swing.JLabel;

import controlador.ContenedorDeErrores;

import eventos.EventoEtiquetaDeGraficable;

import vista.Tema;
import vista.paneles.hojaDibujo.HojaDeDibujo;
import vista.paneles.hojaDibujo.UtilHojaDeDibujo;
import vista.treeDiagrama.NodoTreeDiagrama;
import logica.EntidadRol;
import logica.ObjetoDiagrama;
import logica.persistencia.EntidadRolGraficablePersistente;
import logica.persistencia.GraficableConEtiquetaPersistente;

public class EntidadRolGraficable extends GraficableConEtiqueta implements Identificable {
	
	private EntidadRol entidadRol;
	private EntidadGraficable entidad;
	
	private Point centroRelacion = new Point();
	
	public EntidadRolGraficable(EntidadRol entidadRol, EntidadGraficable entidad)
	{
		super();
		this.entidadRol = entidadRol;
		this.entidad = entidad;
		
		this.setDiagrama(this.entidad.getDiagrama());
		inicializarEtiqueta();
	}

	private void inicializarEtiqueta() {
		this.getEtiqueta().setText(getTexto());
		this.getEtiqueta().setHorizontalAlignment(JLabel.CENTER);
		this.getEtiqueta().setSize(this.getTamano(), 50); // ver de cambiar el 50 ese por algo dinámico
//		this.getEtiqueta().setVerticalAlignment(JLabel.CENTER);
	}

	private String getTexto() 
	{
		String texto = "<html> <center> (";
		
		texto += (this.entidadRol.getCardinalidadMinString() +", " + this.entidadRol.getCardinalidadMaxString()+")");
		texto += ("<br>");
		texto += (this.entidadRol.getRol());
		texto += ("</center></html>");
		return texto;
	}
	
	private int getTamano()
	{
		int stringWidth = this.getEtiqueta().getFontMetrics(this.getEtiqueta().getFont()).stringWidth(this.entidadRol.getRol());
	
		return Math.max(stringWidth, 50);
	}

	@Override
	public void dibujarse(Object areaDeDibujo) 
	{
		GLAutoDrawable gLDrawable = (GLAutoDrawable) areaDeDibujo; 
		GL2 gl = gLDrawable.getGL().getGL2();

		float [] centroRelacion = UtilHojaDeDibujo.getCoordMundo(gl, this.centroRelacion.x, this.centroRelacion.y);
		float [] centroEntidad = UtilHojaDeDibujo.getCoordMundo(gl, this.entidad.getPunto().x, this.entidad.getPunto().y);
		
		gl.glBegin(GL2.GL_LINES);
			gl.glColor3fv(Tema.getInstancia().getLineaColor());
			gl.glVertex2f(centroRelacion[0], centroRelacion[1]);
			gl.glVertex2f(centroEntidad[0], centroEntidad[1]);
		gl.glEnd();
		
		this.setMedio();	
		super.setUbicacionEtiqueta(this.getPunto().x, this.getPunto().y);
	}

	@Override
	public void agregarseAlCanvas(GLJPanel panel, Font fuente, Color color)
	{	
		this.setMedio();
		
		this.getEtiqueta().setLocation(this.getPunto());
			
		super.agregarseAlCanvas(panel, fuente, color);
	}

	private void setMedio() 
	{
		this.getPunto().setLocation(
			(this.entidad.getPunto().x + this.getCentroRelacion().x)/2,
			(this.entidad.getPunto().y + this.getCentroRelacion().y - this.getEtiqueta().getHeight())/2);
	}
	
	
	@Override
	public void setUbicacionEtiqueta(int x, int y) 
	{
		this.setMedio();	
		super.setUbicacionEtiqueta(this.getPunto().x, this.getPunto().y);
	}
	
	@Override
	public ObjetoDiagrama getObjetoDiagramaDecorado() throws NoEsObjetoDiagramableException {
		throw new NoEsObjetoDiagramableException("Un EntidadRolGraficable no decora un ObjetoDiagrama.");
	}

	@Override
	public NodoTreeDiagrama getNodoTreeDiagrama() throws NoEsObjetoNodoException {
		throw new NoEsObjetoNodoException("Un EntidadRolGraficable no puede agrearse al arbol.");
	}
	
	public EntidadGraficable getEntidad() {
		return entidad;
	}

	public void setEntidad(EntidadGraficable entidad) {
		this.entidad = entidad;
	}

	public Point getCentroRelacion() {
		return centroRelacion;
	}

	public void setCentroRelacion(Point centroRelacion) { 
		this.centroRelacion = centroRelacion;
	}

	@Override
	public boolean esElGraficableDe(ObjetoDiagrama objeto) {
		return false;
	}

	@Override
	public void update(Observable arg0, Object arg1) {}

	@Override
	protected EventoEtiquetaDeGraficable getEvento(HojaDeDibujo hoja) {
		return null;
	}

	@Override
	public MouseAdapter getEventoEditarGraficable(JFrame ventanaPadre) {
		return null;
	}

	@Override
	public GraficableConEtiqueta copiarse(IContenedorDeGraficable contenedor)
	{
		for(GraficableConEtiqueta graficable: contenedor.getGraficables())
			if (graficable.esElGraficableDe(entidadRol.getEntidad()))
				return new EntidadRolGraficable(this.entidadRol, (EntidadGraficable)graficable);
		
		return new EntidadRolGraficable(this.entidadRol, (EntidadGraficable)this.getEntidad().copiarse(contenedor));
	}
	
	@Override
	public GraficableConEtiquetaPersistente getGraficableConEtiquetaPersistente() {
		return new EntidadRolGraficablePersistente(this);
	}

	@Override
	public boolean tieneLaEntidad(EntidadGraficable entidadGraficable) {
		return (this.getEntidad() == entidadGraficable);
	}

	@Override
	public boolean sePuedeBorrar(EntidadGraficable entidadGraficable) {
		return tieneLaEntidad(entidadGraficable);
	}

	@Override
	public Point getPuntoInterseccion() 
	{
		Point puntoMedio = new Point();
		
		puntoMedio.x = (3*this.getCentroRelacion().x + this.getEntidad().getPunto().x)/4;
		puntoMedio.y = (3*this.getCentroRelacion().y + this.getEntidad().getPunto().y)/4;
		
		return puntoMedio;
	}

	@Override
	public void validar(ContenedorDeErrores errores) {
		// TODO validar IMPLEMENTAR ERRORES
		
	}
	
	public EntidadRol getEntidadRol() {
		return entidadRol;
	}
}